/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * viewWithChunkedInput.java
 *
 * Created on Aug 6, 2010, 3:58:25 AM
 */

package crfsvm.crf.een_phuong;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.Color;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.BadLocationException;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.Highlighter.HighlightPainter;
import javax.swing.text.JTextComponent;
import java.io.*; //my addition


/**
 *
 * @author Thien
 */
public class viewWithChunkedInput extends javax.swing.JFrame {

    /** Creates new form viewWithChunkedInput */
    public viewWithChunkedInput() {
        try
        {
            this.setTitle("View Tagged Result With Chunked Input Ver 1.0 By Thien Huu Nguyen (Hanoi University of Technology)");
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            initComponents();
        }
        catch (Exception ex)
        {
            System.out.println("Error: " + ex);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lbPath = new javax.swing.JLabel();
        txtFieldPath = new javax.swing.JTextField();
        btnBrowse = new javax.swing.JButton();
        btnPredict = new javax.swing.JButton();
        btnPredictWithConfidence = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtArea = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setName("Form"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance().getContext().getResourceMap(viewWithChunkedInput.class);
        lbPath.setText(resourceMap.getString("lbPath.text")); // NOI18N
        lbPath.setName("lbPath"); // NOI18N

        txtFieldPath.setText(resourceMap.getString("txtFieldPath.text")); // NOI18N
        txtFieldPath.setName("txtFieldPath"); // NOI18N

        btnBrowse.setText(resourceMap.getString("btnBrowse.text")); // NOI18N
        btnBrowse.setName("btnBrowse"); // NOI18N
        btnBrowse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnBrowseActionPerformed(evt);
            }
        });

        btnPredict.setText(resourceMap.getString("btnPredict.text")); // NOI18N
        btnPredict.setName("btnPredict"); // NOI18N
        btnPredict.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPredictActionPerformed(evt);
            }
        });

        btnPredictWithConfidence.setText(resourceMap.getString("btnPredictWithConfidence.text")); // NOI18N
        btnPredictWithConfidence.setName("btnPredictWithConfidence"); // NOI18N
        btnPredictWithConfidence.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPredictWithConfidenceActionPerformed(evt);
            }
        });

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        txtArea.setColumns(20);
        txtArea.setRows(5);
        txtArea.setName("txtArea"); // NOI18N
        jScrollPane1.setViewportView(txtArea);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(55, 55, 55)
                        .addComponent(lbPath)
                        .addGap(18, 18, 18)
                        .addComponent(txtFieldPath, javax.swing.GroupLayout.PREFERRED_SIZE, 357, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(btnBrowse))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(170, 170, 170)
                        .addComponent(btnPredict)
                        .addGap(65, 65, 65)
                        .addComponent(btnPredictWithConfidence)))
                .addContainerGap(240, Short.MAX_VALUE))
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 790, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(19, 19, 19)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lbPath)
                    .addComponent(txtFieldPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnBrowse))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnPredictWithConfidence)
                    .addComponent(btnPredict))
                .addGap(18, 18, 18)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnBrowseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBrowseActionPerformed
        // TODO add your handling code here:
        JFileChooser choose = new JFileChooser();
        int f = choose.showOpenDialog(this);
        if (f == JFileChooser.APPROVE_OPTION) {
            File inFile = choose.getSelectedFile();
            txtFieldPath.setText(inFile.getPath());
        }
    }//GEN-LAST:event_btnBrowseActionPerformed

    private void btnPredictActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPredictActionPerformed
        // TODO add your handling code here:
        try {
            // TODO add your handling code here:
            txtArea.setText("");
            CopyFile copyFile = new CopyFile();
            String tagg = "." + File.separator + "input.txt";
            copyFile.copyfile(txtFieldPath.getText(), tagg);

            JVnRecognizer jVnRecognizer = new JVnRecognizer();
            String[] args = new String[4];
            args[0] = "-modeldir";
            args[1] = "./model";
            args[2] = "-inputfile";
            args[3] = "input.txt";
            jVnRecognizer.main(args);
            BufferedReader in = null;
            String line = null;
            try {
                try {
                    in = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt.wseg"), "UTF-8"));
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
            }
            String ret = "", myret = "";
            Highlighter hilite = txtArea.getHighlighter();

            //My code
            File f = new File(txtFieldPath.getText());
            String myPath = "." + File.separator + "data" + File.separator + "mypredicted" + File.separator + f.getName() + ".predicted";
            BufferedWriter predict = new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream(myPath), "UTF-8"));
            //End my code

            try {
                while ((line = in.readLine()) != null) {
                    if (line.trim().length() == 0) {
                        ret += "\n\n";
                        myret += "\n\n";
                        continue;
                    }
                    //NamedEntity nent;
                    nameEntityForConfidence nent;
                    int curpos = 0;
                    while ((nent = getNextEntityConfidence(line, curpos)) != null) { //nent = getNextEntity(line, curpos)
                        String aheadStr = line.substring(curpos, nent.beginIdx);
                        VnStringTokenizer tk = new VnStringTokenizer(aheadStr, " {}");
                        while (tk.hasMoreTokens()) {
                            String token = tk.nextToken();
                            // my code
                            if (checkPunctuation(token))
                                myret += token + " ";
                            else
                                myret += "[" + token + "] ";
                            //end my code
                            token += " ";
                            ret += token;
                            //myret += token;
                            txtArea.append(token);
                        }
                        // myret += "<" + nent.type + ">" + " ";
                        //my code
                        myret += "<" + nent.type + ">" + " ";
                        //ret += "<" + nent.type + " " + nent.confidence + ">" + " ";
                        //jTextArea1.append("<" + nent.type + " " + nent.confidence + ">" + " ");
                        //end my code
                        VnStringTokenizer entTk = new VnStringTokenizer(nent.instance, " {}");
                        while (entTk.hasMoreTokens()) {
                            String token = entTk.nextToken();
                            // my code
                            if (checkPunctuation(token))
                                myret += token + " ";
                            else
                                myret += "[" + token + "] ";
                            //end my code
                            String retOld = ret;
                            token += " ";
                            ret += token;
                            //myret += token;
                            txtArea.append(token);
                            try {
                                highlight(txtArea, token.trim(), retOld.length(), hilite, nent.type);
                            } catch (BadLocationException ex) {
                                Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        //my code
                        myret += "</" + nent.type + ">" + " ";
                        //ret += "</" + nent.type + ">" + " ";
                        //jTextArea1.append("</" + nent.type + ">" + " ");
                        //end my code

                        curpos = nent.endIdx + 1;
                    }
                    if (curpos < line.length()) {
                        String remain = line.substring(curpos, line.length());
                        VnStringTokenizer tk = new VnStringTokenizer(remain, " ");
                        while (tk.hasMoreTokens()) {
                            String token = tk.nextToken();
                            //System.out.println("token = " + token);
                            // my code
                            if (checkPunctuation(token))
                                myret += token + " ";
                            else
                                myret += "[" + token + "] ";
                            //end my code
                            token += " ";
                            ret += token;
                            //myret += token;
                            txtArea.append(token);
                        }
                    }
                    txtArea.append("\n\n");
                }
                predict.write(myret);
                predict.close();
            } catch (IOException ex) {
                Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_btnPredictActionPerformed

    private void btnPredictWithConfidenceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPredictWithConfidenceActionPerformed
        // TODO add your handling code here:
        try {
            // TODO add your handling code here:
            txtArea.setText("");
            CopyFile copyFile = new CopyFile();
            String tagg = "."  + File.separator + "input.txt";
            copyFile.copyfile(txtFieldPath.getText(), tagg);

            JVnRecognizer jVnRecognizer = new JVnRecognizer();
            String[] args = new String[4];
            args[0] = "-modeldir";
            args[1] = "./model";
            args[2] = "-inputfile";
            args[3] = "input.txt";
            jVnRecognizer.main(args);
            BufferedReader in = null;
            String line = null;
            try {
                try {
                    in = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt.wseg"), "UTF-8"));
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
            }
            String ret = "", myret = "";
            Highlighter hilite = txtArea.getHighlighter();

            //My code
            File f = new File(txtFieldPath.getText());
            String myPath = "." + File.separator + "data" + File.separator + "mypredicted" + File.separator + f.getName() + ".predictedConfi";
            BufferedWriter predict = new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream(myPath), "UTF-8"));
            //End my code

            try {
                while ((line = in.readLine()) != null) {
                    if (line.trim().length() == 0) {
                        ret += "\n\n";
                        myret += "\n\n";
                        continue;
                    }
                    //NamedEntity nent;
                    nameEntityForConfidence nent;
                    int curpos = 0;
                    while ((nent = getNextEntityConfidence(line, curpos)) != null) { //nent = getNextEntity(line, curpos)
                        String aheadStr = line.substring(curpos, nent.beginIdx);
                        VnStringTokenizer tk = new VnStringTokenizer(aheadStr, " "); //" {}"
                        while (tk.hasMoreTokens()) {
                            String token = tk.nextToken();
                            // my code
                            if (checkPunctuation(token))
                                myret += token + " ";
                            else
                                myret += "[" + token + "] ";
                            //end my code
                            token += " ";
                            ret += token;
                            //myret += token;
                            txtArea.append(token);
                        }
                        // myret += "<" + nent.type + ">" + " ";
                        //my code
                        myret += "<" + nent.type + " " + nent.confidence + ">" + " ";
                        ret += "<" + nent.type + " " + nent.confidence + ">" + " ";
                        txtArea.append("<" + nent.type + " " + nent.confidence + ">" + " ");
                        //end my code
                        VnStringTokenizer entTk = new VnStringTokenizer(nent.instance, " ");//" {}"
                        while (entTk.hasMoreTokens()) {
                            String token = entTk.nextToken();
                            // my code
                            if (checkPunctuation(token))
                                myret += token + " ";
                            else
                                myret += "[" + token + "] ";
                            //end my code
                            String retOld = ret;
                            token += " ";
                            ret += token;
                            //myret += token;
                            txtArea.append(token);
                            try {
                                highlight(txtArea, token.trim(), retOld.length(), hilite, nent.type);
                            } catch (BadLocationException ex) {
                                Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        //my code
                        myret += "</" + nent.type + ">" + " ";
                        ret += "</" + nent.type + ">" + " ";
                        txtArea.append("</" + nent.type + ">" + " ");
                        //end my code

                        curpos = nent.endIdx + 1;
                    }
                    if (curpos < line.length()) {
                        String remain = line.substring(curpos, line.length());
                        VnStringTokenizer tk = new VnStringTokenizer(remain, " ");
                        while (tk.hasMoreTokens()) {
                            String token = tk.nextToken();
                            //System.out.println("token = " + token);
                            // my code
                            if (checkPunctuation(token))
                                myret += token + " ";
                            else
                                myret += "[" + token + "] ";
                            //end my code
                            token += " ";
                            ret += token;
                            //myret += token;
                            txtArea.append(token);
                        }
                    }
                    txtArea.append("\n\n");
                }
                predict.write(myret);
                predict.close();
            } catch (IOException ex) {
                Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(EEN_PhuongView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_btnPredictWithConfidenceActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new viewWithChunkedInput().setVisible(true);
            }
        });
    }
    
    private  boolean checkPunctuation(String line)
    {
        boolean result = false;
         String[] punctuations = {".", "," , "!", "(", ")", "[", "]", "{", "}", "$", "?", "@", "\"", "-", "/", "...", ":", "'", ";", "*", "+" , "#",
        "%", "^", "&", "=", "|", "~", "`"};
         
         for (int i = 0; i < punctuations.length; i++)
             if (punctuations[i].equals(line))
             {
                 result = true;
                 break;
             }
         
         return result;
    }

    public void highlight(JTextComponent textComp, String pattern, int i, Highlighter hilite, String color) throws BadLocationException {
//        removeHighlights(textComp);
        try {
            Document doc = textComp.getDocument();
            String text = doc.getText(0, doc.getLength());
//            text = text.substring(i, text.length());
            int pos = i;
            while ((pos = text.indexOf(pattern, pos)) >= 0) {
                if (color.equalsIgnoreCase("num")) {
                    hilite.addHighlight(pos, pos + pattern.length(), numHighlightPainter);
                    pos += pattern.length();
                } else if (color.equalsIgnoreCase("time")) {
                    hilite.addHighlight(pos, pos + pattern.length(), timeHighlightPainter);
                    pos += pattern.length();
                } else if (color.equalsIgnoreCase("per")) {
                    hilite.addHighlight(pos, pos + pattern.length(), perHighlightPainter);
                    pos += pattern.length();
                } else if (color.equalsIgnoreCase("misc")) {
                    hilite.addHighlight(pos, pos + pattern.length(), miscHighlightPainter);
                    pos += pattern.length();
                } else if (color.equalsIgnoreCase("pct")) {
                    hilite.addHighlight(pos, pos + pattern.length(), pctHighlightPainter);
                    pos += pattern.length();
                } else if (color.equalsIgnoreCase("cur")) {
                    hilite.addHighlight(pos, pos + pattern.length(), curHighlightPainter);
                    pos += pattern.length();
                } else if (color.equalsIgnoreCase("loc")) {
                    hilite.addHighlight(pos, pos + pattern.length(), locHighlightPainter);
                    pos += pattern.length();
                } else if (color.equalsIgnoreCase("org")) {
                    hilite.addHighlight(pos, pos + pattern.length(), orgHighlightPainter);
                    pos += pattern.length();
                }
            }
        } catch (BadLocationException e) {
        }
    }
    Highlighter.HighlightPainter numHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.GREEN);
    Highlighter.HighlightPainter timeHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.RED);
    Highlighter.HighlightPainter perHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.CYAN);
    Highlighter.HighlightPainter miscHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.YELLOW);
    Highlighter.HighlightPainter pctHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.GRAY);
    Highlighter.HighlightPainter curHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.blue);
    Highlighter.HighlightPainter locHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.LIGHT_GRAY);
    Highlighter.HighlightPainter orgHighlightPainter = (HighlightPainter) new MyHighlightPainter(Color.MAGENTA);

    class MyHighlightPainter extends DefaultHighlighter.DefaultHighlightPainter {

        public MyHighlightPainter(Color color) {
            super(color);
        }
    }

    class NamedEntity {

        public String type; //time, per,org, loc
        public String instance;
        public int beginIdx;
        public int endIdx;
    }

    class nameEntityForConfidence
    {
        public String type; //time, per,org, loc
        public String instance;
        public int beginIdx;
        public int endIdx;
        public String confidence;
    }

    private NamedEntity getNextEntity(String data, int curpos) {
        NamedEntity nent = null;

        int beginOpenTag = data.indexOf("<", curpos);
        int endOpenTag = data.indexOf(">", beginOpenTag);

        if (beginOpenTag == -1 || endOpenTag == -1) {
            return null;
        }

        String openTag = data.substring(beginOpenTag + 1, endOpenTag).toLowerCase();
        String closeTag = "</" + openTag + ">";

        int closeTagIdx = data.indexOf(closeTag, endOpenTag + 1);

        if (closeTagIdx == -1) {
            return null;
        }

        nent = new NamedEntity();

        nent.beginIdx = beginOpenTag;
        nent.endIdx = closeTagIdx + closeTag.length();
        nent.instance = data.substring(endOpenTag + 1, closeTagIdx).trim();
        nent.type = openTag;

        return nent;
    }

    private nameEntityForConfidence getNextEntityConfidence(String data, int curpos) {
        nameEntityForConfidence nent = null;

        int beginOpenTag = data.indexOf("<", curpos);
        int endOpenTag = data.indexOf(">", beginOpenTag);

        if (beginOpenTag == -1 || endOpenTag == -1) {
            return null;
        }

        String temp = data.substring(beginOpenTag + 1, endOpenTag).toLowerCase();
        int index = temp.indexOf(" ");
        String openTag = temp.substring(0, index);
        String confi = temp.substring(index + 1);
        String closeTag = "</" + openTag + ">";

        int closeTagIdx = data.indexOf(closeTag, endOpenTag + 1);

        if (closeTagIdx == -1) {
            return null;
        }

        nent = new nameEntityForConfidence();

        nent.beginIdx = beginOpenTag;
        nent.endIdx = closeTagIdx + closeTag.length();
        nent.instance = data.substring(endOpenTag + 1, closeTagIdx).trim();
        nent.type = openTag;
        nent.confidence = confi;

        return nent;
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnBrowse;
    private javax.swing.JButton btnPredict;
    private javax.swing.JButton btnPredictWithConfidence;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lbPath;
    private javax.swing.JTextArea txtArea;
    private javax.swing.JTextField txtFieldPath;
    // End of variables declaration//GEN-END:variables

}
